import pyautogui
import tkinter as tk
from PIL import ImageGrab
import numpy as np


class ColorDetector:
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("智能屏幕取色器")

        # 初始化时添加快捷键绑定
        self.root.bind('<Control-s>', lambda event: self.set_target_color())
        self.root.bind('<Control-S>', lambda event: self.set_target_color())

        # 状态变量
        self.target_color = None
        self.tolerance = 10
        self.detecting = False

        # GUI布局
        self.setup_ui()

    def setup_ui(self):
        # 状态显示
        self.status_label = tk.Label(self.root, text="未选择目标颜色\n(使用 Ctrl+S 快速锁定)",
                                     font=('Arial', 12))
        self.status_label.pack(pady=10)

        # 当前颜色显示
        self.current_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.current_frame.pack(pady=5)

        # 目标颜色显示
        self.target_frame = tk.Frame(self.root, width=100, height=100, relief="groove")
        self.target_frame.pack(pady=5)

        # 控制面板
        control_frame = tk.Frame(self.root)
        control_frame.pack(pady=10)

        tk.Label(control_frame, text="容差:").grid(row=0, column=0)
        self.tolerance_entry = tk.Entry(control_frame, width=5)
        self.tolerance_entry.insert(0, "10")
        self.tolerance_entry.grid(row=0, column=1)

        tk.Button(control_frame, text="锁定当前颜色 (Ctrl+S)",
                  command=self.set_target_color).grid(row=0, column=2, padx=5)
        tk.Button(control_frame, text="开始检测",
                  command=self.toggle_detection).grid(row=0, column=3)

        self.info_label = tk.Label(self.root,
                                   text="移动鼠标查看颜色 | Ctrl+S 锁定颜色 | Ctrl+C 退出",
                                   font=('Arial', 10))
        self.info_label.pack(pady=5)

    # 新增缺失的方法
    def toggle_detection(self):
        """切换检测状态"""
        self.detecting = not self.detecting
        if self.detecting and not self.target_color:
            self.status_label.config(text="请先锁定目标颜色！")
            self.detecting = False
            return
        status = "运行中" if self.detecting else "已停止"
        self.status_label.config(text=f"检测状态: {status}")

    def color_distance(self, color1, color2):
        """计算颜色差异（欧氏距离）"""
        return np.sqrt(sum((c1 - c2) ** 2 for c1, c2 in zip(color1, color2)))

    def is_color_in_range(self, current_color):
        """判断颜色是否在目标范围内"""
        if not self.target_color:
            return False
        distance = self.color_distance(current_color, self.target_color)
        return distance <= self.tolerance

    def set_target_color(self, event=None):
        """设置目标颜色（支持快捷键调用）"""
        try:
            x, y = pyautogui.position()
            screenshot = ImageGrab.grab()
            self.target_color = screenshot.getpixel((x, y))
            self.tolerance = int(self.tolerance_entry.get())
            hex_color = '#{:02x}{:02x}{:02x}'.format(*self.target_color)
            self.target_frame.config(bg=hex_color)
            self.status_label.config(text=f"目标颜色已锁定 @ ({x}, {y})\n容差: {self.tolerance}")
            self.current_frame.config(bg='#4CAF50')
            self.root.after(200, lambda: self.current_frame.config(bg=hex_color))
        except Exception as e:
            self.status_label.config(text=f"锁定失败: {str(e)}")

    def update_color(self):
        try:
            x, y = pyautogui.position()
            screenshot = ImageGrab.grab()
            current_color = screenshot.getpixel((x, y))

            hex_color = '#{:02x}{:02x}{:02x}'.format(*current_color)
            self.current_frame.config(bg=hex_color)

            if self.detecting and self.target_color:
                if self.is_color_in_range(current_color):
                    self.root.config(bg="green")
                    self.info_label.config(text="★ 检测到目标颜色！ ★")
                else:
                    self.root.config(bg="white")
                    self.info_label.config(text="移动鼠标查看颜色 | Ctrl+C 退出")

            self.root.after(50, self.update_color)
        except Exception as e:
            print(f"错误: {e}")

    def run(self):
        self.root.after(0, self.update_color)
        self.root.mainloop()


if __name__ == "__main__":
    detector = ColorDetector()
    try:
        detector.run()
    except KeyboardInterrupt:
        print("程序已安全退出")